package org.neptune.service.redis;

import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.neptune.common.util.SerializerUtil;
import org.redisson.api.RBinaryStream;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import com.google.common.collect.Sets;

/**
 * @author lwl
 * @date 2019/8/5 13:20
 */
@Component
public class RedisRepository {

	@Resource(name = "redissonSingle")
	private RedissonClient redissonClient;

	/**
	 * 存入缓存
	 *
	 * @param key
	 * @param value
	 */
	public void set(String key, Object value) {

		RBinaryStream stream = redissonClient.getBinaryStream(key);
		stream.set(SerializerUtil.objToByte(value));
	}

	/**
	 * 存入缓存 包含过期时间
	 *
	 * @param key
	 * @param value
	 * @param expireTime
	 */
	public void set(String key, Object value, int expireTime) {

		RBinaryStream stream = redissonClient.getBinaryStream(key);
		stream.set(SerializerUtil.objToByte(value), expireTime, TimeUnit.MINUTES);
	}

	/**
	 * 存入缓存 包含过期时间 --JDK序列化方式
	 *
	 * @param key
	 * @param value
	 * @param expireTime
	 */
	public void setViaJDK(String key, Object value, int expireTime) {

		RBinaryStream stream = redissonClient.getBinaryStream(key);
		stream.set(SerializerUtil.objToByteJDK(value), expireTime, TimeUnit.MINUTES);
	}

	/**
	 * 从缓存获取值 --JDK方式
	 *
	 * @param key
	 * @return
	 */
	public Object getViaJDK(String key) {
		RBinaryStream stream = redissonClient.getBinaryStream(key);
		if (stream.get() != null && stream.get().length > 0){
			return SerializerUtil.byteToObjJDK(stream.get(), Object.class);
		}
		return null;
	}

	/**
	 * 从缓存获取值并转类型
	 *
	 * @param <T>
	 * @param key
	 * @param clazz
	 * @return
	 */
	// public <泛型声明> T methodName(args...);
	public <T> T get(String key, Class<T> clazz) {
		RBinaryStream stream = redissonClient.getBinaryStream(key);
		if (stream.get() != null && stream.get().length > 0){
			return SerializerUtil.byteToObj(stream.get(), clazz);
		}
		return null;
	}

	/**
	 * 获取过期时间
	 *
	 * @param key
	 * @return
	 */
	public long ttl(String key) {
		return redissonClient.getPermitExpirableSemaphore(key).remainTimeToLive();
	}

	/**
	 * 移出缓存
	 *
	 * @param key
	 * @return
	 */
	public boolean remove(String key) {
		return redissonClient.getRateLimiter(key).delete();
	}

	/**
	 * 递增
	 *
	 * @param key
	 * @param expire
	 * @return
	 */
	public long increment(String key, int expire) {
		long num = redissonClient.getAtomicLong(key).incrementAndGet();
		redissonClient.getAtomicLong(key).expire(expire, TimeUnit.MINUTES);
		return num;
	}

	/**
	 * 递减
	 *
	 * @param key
	 * @param expire
	 * @return
	 */
	public long decrement(String key, int expire) {
		long num = redissonClient.getAtomicLong(key).decrementAndGet();
		redissonClient.getAtomicLong(key).expire(expire, TimeUnit.MINUTES);
		return num;
	}

	/**
	 * 递增指定的值
	 *
	 * @param key
	 * @param addNum
	 * @param expire
	 * @return
	 */
	public long incrementWithNum(String key, long addNum, int expire) {
		long num = redissonClient.getAtomicLong(key).addAndGet(addNum);
		redissonClient.getAtomicLong(key).expire(expire, TimeUnit.MINUTES);
		return num;
	}

	/**
	 * 递减指定的值
	 *
	 * @param key
	 * @param delNum
	 * @param expire
	 * @return
	 */
	public long decrementWithNum(String key, long delNum, int expire) {
		long num = redissonClient.getAtomicLong(key).addAndGet(-delNum);
		redissonClient.getAtomicLong(key).expire(expire, TimeUnit.MINUTES);
		return num;
	}

	/**
	 * 递增并返回
	 *
	 * @param key
	 * @param expire
	 * @return
	 */
	public int incrementReturnint(String key, int expire) {
		Long num = this.increment(key, expire);
		return num.intValue();
	}

	/**
	 * 递减并返回
	 *
	 * @param key
	 * @param expire
	 * @return
	 */
	public int decrementReturnint(String key, int expire) {
		Long num = this.decrement(key, expire);
		return num.intValue();
	}

	/**
	 * 设置过期时间
	 *
	 * @param key
	 * @param time
	 */
	public void expire(String key, long time) {
		redissonClient.getBinaryStream(key).expire(time, TimeUnit.SECONDS);
	}

	/**
	 * 获取数值
	 *
	 * @param key
	 * @return
	 */
	public long getLong(String key) {
		long count = redissonClient.getAtomicLong(key).addAndGet(0);
		return count;
	}

	/**
	 * 是否存在
	 *
	 * @param key
	 * @return
	 */
	public boolean hasKey(String key) {
		boolean result = redissonClient.getBucket(key).isExists();
		return result;
	}

	/**
	 * 批量获取key
	 *
	 * @param pattern
	 * @return
	 */
	public Set<String> getKeysByPattern(String pattern) {
		Set<String> keys = Sets.newHashSet();
		Iterable<String> result = redissonClient.getKeys().getKeysByPattern(pattern);
		for (String s : result){
			keys.add(s);
		}
		return keys;
	}

}
